﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;

namespace DAL
{
    /// <summary>
    /// Repository基类
    /// 所有linqTosql上下文对象都继承它
    /// </summary>
    public abstract class ContextBase<TEntity> : ICompleteRepository<TEntity> where TEntity : class
    {
        #region Constructors
        public ContextBase(DataContext db)
        {
            _db = db;
            IUnitOfWork = (IUnitOfWork)db;
        }
        #endregion

        #region Properties
        /// <summary>
        /// 数据上下文
        /// </summary>
        protected DataContext _db { get; private set; }
        /// <summary>
        /// 工作单元上下文
        /// </summary>
        protected IUnitOfWork IUnitOfWork { get; private set; }
        #endregion

        #region Protected Methods
        /// <summary>
        /// 提交到数据库，子类统一调用这个方法进行提交
        /// </summary>
        protected void SaveChanges()
        {
            ChangeSet cSet = _db.GetChangeSet();
            if ((cSet.Inserts.Count > 0
                || cSet.Updates.Count > 0
                || cSet.Deletes.Count > 0)
                && !IUnitOfWork.IsNotSubmit)
            {
                try
                {
                    IUnitOfWork.SaveChanges();
                }
                catch (System.Data.Linq.ChangeConflictException)
                {

                    foreach (System.Data.Linq.ObjectChangeConflict occ in _db.ChangeConflicts)
                    {
                        // 使用当前数据库中的值，覆盖Linq缓存中实体对象的值  
                        occ.Resolve(System.Data.Linq.RefreshMode.OverwriteCurrentValues);
                        // 使用Linq缓存中实体对象的值，覆盖当前数据库中的值  
                        occ.Resolve(System.Data.Linq.RefreshMode.KeepCurrentValues);
                        // 只更新实体对象中改变的字段的值，其他的保留不变  
                        occ.Resolve(System.Data.Linq.RefreshMode.KeepChanges);
                    }
                    IUnitOfWork.SaveChanges();
                }
            }
        }
        #endregion

        #region IRepository<TEntity> 成员

        public virtual void Insert(TEntity item)
        {
            this._db.GetTable<TEntity>().InsertOnSubmit(item);
            SaveChanges();
        }

        public virtual void Delete(TEntity item)
        {
            _db.GetTable<TEntity>().DeleteOnSubmit(item);
            SaveChanges();
        }

        public virtual void Update(TEntity item)
        {
            SaveChanges();
        }

        public IQueryable<TEntity> GetModel()
        {
            return _db.GetTable<TEntity>();
        }

        public TEntity Find(params object[] id)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IExtensionRepository<TEntity> 成员

        public virtual void Insert(IEnumerable<TEntity> item)
        {

            this._db.GetTable<TEntity>().InsertAllOnSubmit(item);
            SaveChanges();
        }

        public virtual void Update(IEnumerable<TEntity> item)
        {
            SaveChanges();
        }

        public virtual void Delete(IEnumerable<TEntity> item)
        {
            _db.GetTable<TEntity>().DeleteAllOnSubmit(item);
            SaveChanges();
        }

        #endregion
    }
}
